PART I: EDA

Package installation.

Connecting the database.

General EDA.

Getting data.

df_segments_length <- data.frame()
df_segments_length_tm <- dbGetQuery(con, "SELECT session_id, SUM(length) as distance, travelmode
                                      FROM danielasocas.segments_travelmode as segments 
                                      WHERE segments.travelmode = 'car' OR segments.travelmode = 'bus'
                                      GROUP BY session_id, travelmode")

df_segments_length <- dbGetQuery(con, "SELECT session_id, SUM(length) as distance
                                      FROM danielasocas.segments_travelmode as segments 
                                      WHERE segments.travelmode = 'car' OR segments.travelmode = 'bus'
                                      GROUP BY session_id")
df_segments <- subset(df_segments_length, distance < IQR(distance,0.75) )

ggplot(df_segments, aes(distance)) +
  geom_histogram(bins = 10)

ggplot(df_segments_length, aes(travelmode, distance, color = travelmode)) +
  geom_boxplot()

ggplot(df_segments, aes(distance, color = travelmode)) +
  geom_histogram(binwidth = 1)

ggplot(df_segments, aes(travelmode, distance, color = travelmode)) +
  geom_boxplot()
df_segments_timestamp <- data.frame()
df_segments_timestamp <- dbGetQuery(con, "SELECT session_id, time_start,time_end, length, travelmode
                                      FROM danielasocas.segments_travelmode as segments
                                      WHERE segments.travelmode = 'car' OR segments.travelmode = 'bus'")

Getting data per edge.

POINTS per edge.

Getting the points filtered by only segments with travelmode = car or bus.

SESSION per edge.

Getting the sessions filtered by only segments with travelmode = car or bus.


df_sessions_edge_osm_cars <- data.frame()
df_sessions_edge_osm_cars <- dbGetQuery(con, "SELECT way_id, COUNT(DISTINCT session_id) AS sessions
                                   FROM sensemyfeup_raw.osmlocation as osm 
                                          INNER JOIN danielasocas.segments_travelmode as segments 
                                            USING (session_id)
                                          INNER JOIN sensemyfeup_raw.session_offsets 
                                            USING (session_id)
                                       WHERE (osm.seconds + session_offsets.clock_offset_seconds BETWEEN segments.seconds_start AND seconds_end) AND
                                            segments.travelmode = 'car' OR segments.travelmode =  'bus'
                                       GROUP BY way_id
                                       ORDER BY sessions DESC")

save(df_sessions_edge_osm_cars, file="df_sessions_edge_osm_cars.Rda")

Plots edges and loading.

POINTS

p1 <- subset(df_osm_edge, points < mean(points)) 
summary()

ggplot(p1, aes(points)) + geom_histogram(binwidth = 10) +
  xlim(0,1000)

ECDF

SESSIONS

p1 <- subset(df_osm_edge, sessions < mean(sessions)) 
summary()

ggplot(p1, aes(sessions)) + geom_histogram(binwidth=1) +
  scale_x_continuous(breaks = seq(0,8,1))

ECDF

list_osm_edge <- df_osm_edge[, 1]

fun.ecdf <- ecdf(df_osm_edge$sessions)

my.ecdf <- fun.ecdf(sort(df_osm_edge$sessions))

my_ecdf_df <- data.frame(my.ecdf)

my_ecdf_df$sessions <- sort(df_osm_edge$sessions)

tail(my_ecdf_df, 400)

P <- ecdf(df_osm_edge$sessions)
plot(P, log="x", xlim=c(1, max(df_osm_edge$sessions)))

Map points/sessions per edge.

Mapping

# Showing Map.
m 

Writing the results

Disconnecting Databases.

LS0tCnRpdGxlOiAiU2Vuc2UgTXkgRkVVUCAtIE1vYmlsaXR5IGZvcmVjYXN0aW5nIGJhc2VkIG9uIEdQUyBsb2NhdGlvbiB0cmFja2luZyIKYXV0aG9yOiAiRGFuaWVsYSBTLiBHaWwiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgUEFSVCBJOiBFREEgCgojIyBQYWNrYWdlIGluc3RhbGxhdGlvbi4gCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiNCYXNpY3MuIAoKaWYoISAiZ2dwbG90MiIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQp9CgppZighICJkcGx5ciIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikKfQoKaWYoISAidGlkeXIiICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5ciIpCn0KCmlmKCEgInhsc3giICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJ4bHN4IikKfQoKaWYoISAibWFncml0dHIiICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJtYWdyaXR0ciIpCn0KCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeSh4bHN4KQojbGlicmFyeShtYWdyaXR0cikKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojY29ubmVjdGlvbiB0byBkYXRhYmFzZS4KCmlmKCEgIkRCSSIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoIkRCSSIpCn0KaWYoISAiUlBvc3RncmVTUUwiICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJSUG9zdGdyZVNRTCIpCn0KCmxpYnJhcnkoREJJKQpsaWJyYXJ5KFJQb3N0Z3JlU1FMKQpgYGAKCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiNNYXBwaW5nLiAKCmlmKCEgImxlYWZsZXQiICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFmbGV0IikKfQoKaWYoISAibGVhZmxldCIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoImdnbWFwIikKICBsaWJyYXJ5KGdnbWFwKQp9CgppZighICJzcCIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoInNwIikKICBsaWJyYXJ5KHNwKQp9CgpsaWJyYXJ5KGxlYWZsZXQpCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KI1RpbWUgbWFuYWdlbWVudC4KCmlmKCEgImx1YnJpZGF0ZSIgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkpewogIGluc3RhbGwucGFja2FnZXMoImx1YnJpZGF0ZSIpCn0KCmxpYnJhcnkobHVicmlkYXRlKQpgYGAKCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiNXcml0ZSBFeGNlbApsaWJyYXJ5KHhsc3gpCmxpYnJhcnkockphdmEpCmxpYnJhcnkoeGxzeGphcnMpCmBgYAoKCiMjIENvbm5lY3RpbmcgdGhlIGRhdGFiYXNlLgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojIENvbm5lY3RpbmcgU2Vuc2UgTXkgRkVVUCAtIERTCgpkcnYgPC0gZGJEcml2ZXIoIlBvc3RncmVTUUwiKQpwd2QgPC0gInBzaWNvcGF0YXMiCgojRGF0YWJhc2UgdG8gY29ubmVjdCAKZGIgPC0gInNlbnNlbXlmZXVwIgojZGIgPC0gc2Vuc2VteWNpdHkKCmNvbiA8LWRiQ29ubmVjdChkcnYsaG9zdD0nbG9jYWxob3N0Jyxwb3J0PScxNTQzMicsZGJuYW1lPWRiLHVzZXI9J2RhbmllbGFzb2NhcycsCnBhc3N3b3JkPXB3ZCkKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojIENvbm5lY3RpbmcgT3BlblN0cmVldE1hcCAtIE1hcmNpbyBGb250ZXMKcHcgPC0gewogICJ5N2RXd0J5WkxXc28iCn0KCmRydiA8LSBkYkRyaXZlcigiUG9zdGdyZVNRTCIpCgpjb25fb3NtIDwtIGRiQ29ubmVjdChkcnYsIGRibmFtZSA9ICJvcGVuc3RyZWV0bWFwIiwKICAgICAgICAgICAgICAgICAgICAgaG9zdCA9ICJsb2NhbGhvc3QiLCBwb3J0ID0gMTU0MzIsCiAgICAgICAgICAgICAgICAgICAgIHVzZXIgPSAibWFyY2lvZm9udGVzIiwgcGFzc3dvcmQgPSBwdykKYGBgCgojIyBHZW5lcmFsIEVEQS4KIyMjIEdldHRpbmcgZGF0YS4gCmBgYHtyfQpkZl9zZWdtZW50c19sZW5ndGggPC0gZGF0YS5mcmFtZSgpCmRmX3NlZ21lbnRzX2xlbmd0aF90bSA8LSBkYkdldFF1ZXJ5KGNvbiwgIlNFTEVDVCBzZXNzaW9uX2lkLCBTVU0obGVuZ3RoKSBhcyBkaXN0YW5jZSwgdHJhdmVsbW9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZST00gZGFuaWVsYXNvY2FzLnNlZ21lbnRzX3RyYXZlbG1vZGUgYXMgc2VnbWVudHMgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgc2VnbWVudHMudHJhdmVsbW9kZSA9ICdjYXInIE9SIHNlZ21lbnRzLnRyYXZlbG1vZGUgPSAnYnVzJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdST1VQIEJZIHNlc3Npb25faWQsIHRyYXZlbG1vZGUiKQoKZGZfc2VnbWVudHNfbGVuZ3RoIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNlc3Npb25faWQsIFNVTShsZW5ndGgpIGFzIGRpc3RhbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJPTSBkYW5pZWxhc29jYXMuc2VnbWVudHNfdHJhdmVsbW9kZSBhcyBzZWdtZW50cyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSEVSRSBzZWdtZW50cy50cmF2ZWxtb2RlID0gJ2NhcicgT1Igc2VnbWVudHMudHJhdmVsbW9kZSA9ICdidXMnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR1JPVVAgQlkgc2Vzc2lvbl9pZCIpCmBgYAoKYGBge3J9CmRmX3NlZ21lbnRzIDwtIHN1YnNldChkZl9zZWdtZW50c19sZW5ndGgsIGRpc3RhbmNlIDwgSVFSKGRpc3RhbmNlLDAuNzUpICkKCmdncGxvdChkZl9zZWdtZW50cywgYWVzKGRpc3RhbmNlKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCkKCmdncGxvdChkZl9zZWdtZW50c19sZW5ndGgsIGFlcyh0cmF2ZWxtb2RlLCBkaXN0YW5jZSwgY29sb3IgPSB0cmF2ZWxtb2RlKSkgKwogIGdlb21fYm94cGxvdCgpCgpnZ3Bsb3QoZGZfc2VnbWVudHMsIGFlcyhkaXN0YW5jZSwgY29sb3IgPSB0cmF2ZWxtb2RlKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkKCmdncGxvdChkZl9zZWdtZW50cywgYWVzKHRyYXZlbG1vZGUsIGRpc3RhbmNlLCBjb2xvciA9IHRyYXZlbG1vZGUpKSArCiAgZ2VvbV9ib3hwbG90KCkKYGBgCgoKYGBge3J9CmRmX3NlZ21lbnRzX3RpbWVzdGFtcCA8LSBkYXRhLmZyYW1lKCkKZGZfc2VnbWVudHNfdGltZXN0YW1wIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHNlc3Npb25faWQsIHRpbWVfc3RhcnQsdGltZV9lbmQsIGxlbmd0aCwgdHJhdmVsbW9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZST00gZGFuaWVsYXNvY2FzLnNlZ21lbnRzX3RyYXZlbG1vZGUgYXMgc2VnbWVudHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSEVSRSBzZWdtZW50cy50cmF2ZWxtb2RlID0gJ2NhcicgT1Igc2VnbWVudHMudHJhdmVsbW9kZSA9ICdidXMnIikKYGBgCgoKYGBge3J9CgpgYGAKCiMjIEdldHRpbmcgZGF0YSBwZXIgZWRnZS4KCiMjIyBQT0lOVFMgcGVyIGVkZ2UuIApHZXR0aW5nIHRoZSBwb2ludHMgZmlsdGVyZWQgYnkgb25seSBzZWdtZW50cyB3aXRoIHRyYXZlbG1vZGUgPSBjYXIgb3IgYnVzLgoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KI09idGFpbmluZyB0aGUgcG9pbnRzIHRocm91Z2ggdGhlIHNlc3Npb24gYW5kIHRoZSBzZWNvbmRzIG9mIHRoZSB3aG9sZSBzZWdtZW50LiAgCgpkZl9wb2ludHNfZWRnZV9vc21fY2FycyA8LSBkYXRhLmZyYW1lKCkKZGZfcG9pbnRzX2VkZ2Vfb3NtX2NhcnMgPC0gZGJHZXRRdWVyeShjb24sICJTRUxFQ1Qgd2F5X2lkLCBDT1VOVCgqKSBBUyBwb2ludHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJPTSBzZW5zZW15ZmV1cF9yYXcub3NtbG9jYXRpb24gYXMgb3NtIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTk5FUiBKT0lOIGRhbmllbGFzb2Nhcy5zZWdtZW50c190cmF2ZWxtb2RlIGFzIHNlZ21lbnRzIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTSU5HIChzZXNzaW9uX2lkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTk5FUiBKT0lOIHNlbnNlbXlmZXVwX3Jhdy5zZXNzaW9uX29mZnNldHMgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVNJTkcgKHNlc3Npb25faWQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdIRVJFIChvc20uc2Vjb25kcyArIHNlc3Npb25fb2Zmc2V0cy5jbG9ja19vZmZzZXRfc2Vjb25kcyBCRVRXRUVOIHNlZ21lbnRzLnNlY29uZHNfc3RhcnQgQU5EIHNlY29uZHNfZW5kKSBBTkQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWdtZW50cy50cmF2ZWxtb2RlID0gJ2NhcicgT1Igc2VnbWVudHMudHJhdmVsbW9kZSA9ICAnYnVzJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHUk9VUCBCWSB3YXlfaWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JERVIgQlkgcG9pbnRzIERFU0MiKQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhdmUoZGZfcG9pbnRzX2VkZ2Vfb3NtX2NhcnMsIGZpbGU9ImRmX3BvaW50c19lZGdlX29zbV9jYXJzMi5SZGEiKQpgYGAKCiMjIyBTRVNTSU9OIHBlciBlZGdlLiAKR2V0dGluZyB0aGUgc2Vzc2lvbnMgZmlsdGVyZWQgYnkgb25seSBzZWdtZW50cyB3aXRoIHRyYXZlbG1vZGUgPSBjYXIgb3IgYnVzLgoKYGBge3J9CgpkZl9zZXNzaW9uc19lZGdlX29zbV9jYXJzIDwtIGRhdGEuZnJhbWUoKQpkZl9zZXNzaW9uc19lZGdlX29zbV9jYXJzIDwtIGRiR2V0UXVlcnkoY29uLCAiU0VMRUNUIHdheV9pZCwgQ09VTlQoRElTVElOQ1Qgc2Vzc2lvbl9pZCkgQVMgc2Vzc2lvbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUk9NIHNlbnNlbXlmZXVwX3Jhdy5vc21sb2NhdGlvbiBhcyBvc20gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOTkVSIEpPSU4gZGFuaWVsYXNvY2FzLnNlZ21lbnRzX3RyYXZlbG1vZGUgYXMgc2VnbWVudHMgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVNJTkcgKHNlc3Npb25faWQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOTkVSIEpPSU4gc2Vuc2VteWZldXBfcmF3LnNlc3Npb25fb2Zmc2V0cyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0lORyAoc2Vzc2lvbl9pZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgKG9zbS5zZWNvbmRzICsgc2Vzc2lvbl9vZmZzZXRzLmNsb2NrX29mZnNldF9zZWNvbmRzIEJFVFdFRU4gc2VnbWVudHMuc2Vjb25kc19zdGFydCBBTkQgc2Vjb25kc19lbmQpIEFORAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnRzLnRyYXZlbG1vZGUgPSAnY2FyJyBPUiBzZWdtZW50cy50cmF2ZWxtb2RlID0gICdidXMnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdST1VQIEJZIHdheV9pZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUkRFUiBCWSBzZXNzaW9ucyBERVNDIikKCnNhdmUoZGZfc2Vzc2lvbnNfZWRnZV9vc21fY2FycywgZmlsZT0iZGZfc2Vzc2lvbnNfZWRnZV9vc21fY2Fycy5SZGEiKQpgYGAKCgojIyBQbG90cyBlZGdlcyBhbmQgbG9hZGluZy4KIyMjIFBPSU5UUyAKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KIyBSRUZFUkVOQ0UgQlkgUE9JTlRTCiNMb2FkaW5nIGRmIGFib3V0IHRvIHVzZS4KCmxvYWQoImRmX3BvaW50c19lZGdlX29zbV9jYXJzLlJkYSIpCmRmX29zbV9lZGdlIDwtIGRmX3BvaW50c19lZGdlX29zbV9jYXJzCgpgYGAKCmBgYHtyfQpwMSA8LSBzdWJzZXQoZGZfb3NtX2VkZ2UsIHBvaW50cyA8IG1lYW4ocG9pbnRzKSkgCnN1bW1hcnkoKQoKZ2dwbG90KHAxLCBhZXMocG9pbnRzKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEwKSArCiAgeGxpbSgwLDEwMDApCgoKYGBgCgojIyMjRUNERiAKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KIyBMaXN0aW5nIGFuZCBvYnRhaW5pbmcgRUNERiBwZiB0aGUgcG9pbnRzLgoKcHJ0IDwtIDEKc2V0LnNlZWQoNDIxOCkKc3AgPC0gc2FtcGxlKDE6bnJvdyhkZl9vc21fZWRnZSksIGFzLmludGVnZXIocHJ0ICogbnJvdyhkZl9vc21fZWRnZSkpKQoKbGlzdF9vc21fZWRnZSA8LSBkZl9vc21fZWRnZVtzcCwgMV0KCmZ1bi5lY2RmIDwtIGVjZGYoZGZfb3NtX2VkZ2UkcG9pbnRzKQoKbXkuZWNkZiA8LSBmdW4uZWNkZihzb3J0KGRmX29zbV9lZGdlJHBvaW50cykpCgpteV9lY2RmX2RmIDwtIGRhdGEuZnJhbWUobXkuZWNkZikKCm15X2VjZGZfZGYkcG9pbnRzIDwtIHNvcnQoZGZfb3NtX2VkZ2UkcG9pbnRzKQoKdGFpbChteV9lY2RmX2RmLCA0MDApCgpQIDwtIGVjZGYoc3Vic2V0KGRmX29zbV9lZGdlLCBwb2ludHMgPCBxdWFudGlsZShkZl9vc21fZWRnZSRwb2ludHMsLjkpKSRwb2ludHMpCiNncmlkKCkKYGBgCgpgYGB7ciBldmFsPSBUUlVFfQpwbG90KFAsIGxvZz0ieCIsIHhsaW09YygxLCBtYXgoZGZfb3NtX2VkZ2UkcG9pbnRzKSkpCnBsb3QoUCkKYGBgCgojIyMgU0VTU0lPTlMgCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiNSRUZFUkVOQ0UgQlkgU0VTU0lPTlMKCmxvYWQoImRmX3Nlc3Npb25zX2VkZ2Vfb3NtX2NhcnMuUmRhIikKZGZfb3NtX2VkZ2UgPC0gZGZfc2Vzc2lvbnNfZWRnZV9vc21fY2FycwpgYGAKCgpgYGB7cn0KcDEgPC0gc3Vic2V0KGRmX29zbV9lZGdlLCBzZXNzaW9ucyA8IG1lYW4oc2Vzc2lvbnMpKSAKc3VtbWFyeSgpCgpnZ3Bsb3QocDEsIGFlcyhzZXNzaW9ucykpICsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCw4LDEpKQoKYGBgCgojIyMjRUNERgpgYGB7cn0KbGlzdF9vc21fZWRnZSA8LSBkZl9vc21fZWRnZVssIDFdCgpmdW4uZWNkZiA8LSBlY2RmKGRmX29zbV9lZGdlJHNlc3Npb25zKQoKbXkuZWNkZiA8LSBmdW4uZWNkZihzb3J0KGRmX29zbV9lZGdlJHNlc3Npb25zKSkKCm15X2VjZGZfZGYgPC0gZGF0YS5mcmFtZShteS5lY2RmKQoKbXlfZWNkZl9kZiRzZXNzaW9ucyA8LSBzb3J0KGRmX29zbV9lZGdlJHNlc3Npb25zKQoKdGFpbChteV9lY2RmX2RmLCA0MDApCgpQIDwtIGVjZGYoZGZfb3NtX2VkZ2Ukc2Vzc2lvbnMpCmBgYAoKYGBge3IgZXZhbD0gVFJVRX0KcGxvdChQLCBsb2c9IngiLCB4bGltPWMoMSwgbWF4KGRmX29zbV9lZGdlJHNlc3Npb25zKSkpCmBgYAoKIyMgTWFwIHBvaW50cy9zZXNzaW9ucyBwZXIgZWRnZS4KCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiMgTWFwIGNvbG9yIHBhcmFtZXRlci4gCgojIFJlcXVpcmUgdG8gYmUgY29ubmVjdGVkIHRvIGNvbl9vc20KIyBHb2luZyB0aHJvdWdoIGV2ZXJ5IHBvaW50IG9mIHRoZSBkZiBzZWxlY3RlZCAKCiMgRGVmaW5pbmcgbGltaXRzIHRvIGV2ZXJ5IGNvbG9yLiAKIyBNb3JlIHRoYW4gc3VwZXJpb3IgaXMgcmVkLgojIE1vcmUgdGhhbiBtZWRpbyBhbmQgbGVzcyB0aGFuIHN1cGVyaW9yIGlzIHllbGxvdy4KIyBMZXNzIHRoYW4gbWVkaW8gaXMgZ3JlZW4uICAgICAKCiNQb2ludHMKc3VwZXJpb3IgPC0gcXVhbnRpbGUoZGZfb3NtX2VkZ2UkcG9pbnRzLCAwLjkpCm1lZGlvIDwtIHF1YW50aWxlKGRmX29zbV9lZGdlJHBvaW50cywgMC43KQpsb3cgPC0gcXVhbnRpbGUoZGZfb3NtX2VkZ2UkcG9pbnRzLCAwLjUpIAoKI1Nlc3Npb25zIAojc3VwZXJpb3IgPC0gcXVhbnRpbGUoZGZfb3NtX2VkZ2Ukc2Vzc2lvbnMsIDAuOSkKI21lZGlvIDwtIHF1YW50aWxlKGRmX29zbV9lZGdlJHNlc3Npb25zLCAwLjcpCiNsb3cgPC0gcXVhbnRpbGUoZGZfb3NtX2VkZ2Ukc2Vzc2lvbnMsIDAuNSkgCmBgYAoKIyMjIE1hcHBpbmcgCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiMgQ3JlYXRpbmcgdGhlIGVtcHR5IG1hcCBvZiBQb3J0bwoKbSA8LSBsZWFmbGV0KCkgJT4lIHNldFZpZXcobG5nPS04LjYxNDE5LCBsYXQ9NDEuMTYzMTEsIHpvb20gPSAxMykKbSA8LSBhZGRUaWxlcyhtKSAKbSA8LSBhZGRQcm92aWRlclRpbGVzKG0sICJDYXJ0b0RCLlBvc2l0cm9uIikKCmNvdW50ZXIgPC0gMQoKZm9yKHdheV9pZCBpbiBsaXN0X29zbV9lZGdlKSB7CiAgCiAgZGZfd2F5X2lkIDwtIGRiR2V0UXVlcnkoY29uX29zbSwgcGFzdGUwKCJTRUxFQ1Qgc3RfYXN0ZXh0KHN0X3RyYW5zZm9ybSh3YXksIDQzMjYpKSBBUyBsaW5lIEZST00gcGxhbmV0X29zbV9saW5lIFdIRVJFIHBsYW5ldF9vc21fbGluZS5vc21faWQgPSAiLCB3YXlfaWQpKQogIAogIGxpbmUgPC0gZGZfd2F5X2lkJGxpbmUKICBsaW5lIDwtIGFzLmNoYXJhY3RlcihsaW5lKQogIAogIGxpbmUgPC0gdW5saXN0KHN0cnNwbGl0KGxpbmUsIHNwbGl0PScoJywgZml4ZWQ9VFJVRSkpWzJdCiAgbGluZSA8LSBzdWJzdHIobGluZSwgMSwgbmNoYXIobGluZSkgLSAxKQogIAogIHBhcnNlZF9saW5lIDwtIHN0cnNwbGl0KGxpbmUsICIsIikKICAKICBsb25zIDwtIGMoKQogIGxhdHMgPC0gYygpCiAgCiAgaWYobGVuZ3RoKHBhcnNlZF9saW5lKSAhPSAwKSB7CiAgICAKICAgICNEZWZpbmluZyBsb25zIGFuZCBsYXRzIGFzIHZhcmlhYmxlcyB0byB1c2UgbGF0ZXIuCgogICAgZm9yKGNvb3JkIGluIHBhcnNlZF9saW5lW1sxXV0pIHsKICAgICAgCiAgICAgIGxvbiA8LSB1bmxpc3Qoc3Ryc3BsaXQoY29vcmQsIHNwbGl0PScgJywgZml4ZWQ9VFJVRSkpWzFdCiAgICAgIGxhdCA8LSB1bmxpc3Qoc3Ryc3BsaXQoY29vcmQsIHNwbGl0PWxvbiwgZml4ZWQ9VFJVRSkpWzJdCiAgICAgIGxhdCA8LSBzdWJzdHIobGF0LCAyLCBuY2hhcihsYXQpKQogICAgICAKICAgICAgbG9uIDwtIGFzLm51bWVyaWMobG9uKQogICAgICBsYXQgPC0gYXMuZG91YmxlKGxhdCkKICAgICAgCiAgICAgIGxvbnMgPC0gYyhsb25zLCBsb24pCiAgICAgIGxhdHMgPC0gYyhsYXRzLCBsYXQpCiAgICAgIAogICAgfQogICAgCiAgICAjIERlY2lkaW5nIHRoZSBjb2xvciBvZiB0aGUgcG9pbnQuCgogICAgaWYoZGZfb3NtX2VkZ2VbY291bnRlciwgMl0gPiBzdXBlcmlvcikgewogICAgICAgICAgCiAgICAgICAgICBtIDwtIGFkZFBvbHlsaW5lcyhtLCBsb25zLCBsYXRzLCBjb2xvcj0ncmVkJykKICAgICAgICAgIAogICAgICAgIH0gZWxzZSBpZiAoZGZfb3NtX2VkZ2VbY291bnRlciwgMl0gPj0gbWVkaW8gJiYgZGZfb3NtX2VkZ2VbY291bnRlciwgMl0gPD0gc3VwZXJpb3IpIHsKICAgICAgICAgIAogICAgICAgICAgbSA8LSBhZGRQb2x5bGluZXMobSwgbG9ucywgbGF0cywgY29sb3I9J3llbGxvdycpCiAgICAgICAgICAKICAgICAgICB9IGVsc2UgaWYgKGRmX29zbV9lZGdlW2NvdW50ZXIsIDJdID49IGxvdyAmJiBkZl9vc21fZWRnZVtjb3VudGVyLCAyXSA8PSBtZWRpbykgewogICAgICAgICAgCiAgICAgICAgICBtIDwtIGFkZFBvbHlsaW5lcyhtLCBsb25zLCBsYXRzLCBjb2xvcj0nZ3JlZW4nKQogICAgICAgICAgCiAgICAgICAgfQogICAgICAgIAogICAgICAgIGNvdW50ZXIgPC0gY291bnRlciArIDEgCiAgICAgICAgCiAgICAgIH0KICAgICAgCiAgICAgICNwcmludChsaW5lKQogICAgICAKICAgIH0KCmBgYAoKYGBge3IgZXZhbD0gVFJVRX0KIyBTaG93aW5nIE1hcC4KbSAKYGBgCgojIyBXcml0aW5nIHRoZSByZXN1bHRzCgpgYGB7ciBlY2hvPUZBTFNFfQojUG9pbnRzCndyaXRlLnhsc3goZGZfb3NtX2VkZ2UsIGZpbGU9ImRmX3BvaW50c19lZGdlX29zbS54bHN4IikKCiNTZXNzaW9ucwp3cml0ZS54bHN4KGRmX29zbV9lZGdlLCBmaWxlPSJkZl9zZXNzaW9uc19lZGdlX29zbS54bHN4IikKCmBgYAoKCiMgRGlzY29ubmVjdGluZyBEYXRhYmFzZXMuCmBgYHtyIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CmRiRGlzY29ubmVjdChjb25fb3NtKQpkYkRpc2Nvbm5lY3QoY29uKQoKYGBgCgo=